from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import StreamingResponse
import io
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List, Dict, Any

from database.database import get_db
from core.base.api_mode import ApiResponse, api_success
from modules.code_genrator.services.code_service import CodeService
from modules.code_genrator.services.gen_business_service import GenBusinessService
from modules.code_genrator.schemas.code_schema import ImportRequest


router = APIRouter()


@router.get("/tables/{table_schema}", response_model=ApiResponse[List[Dict[str, Any]]])
async def get_tables(table_schema: str, db: AsyncSession = Depends(get_db)):
    """获取指定 schema 下的所有表信息"""
    tables = await CodeService.get_all_tables(db=db, table_schema=table_schema)
    # RowMapping 不可直接序列化，转换为普通字典
    payload = [dict(row) for row in tables]
    return api_success(payload, msg="获取成功")


@router.post("/import", response_model=ApiResponse[dict])
async def import_business_and_model(req: ImportRequest, db: AsyncSession = Depends(get_db)):
    """根据表信息导入业务与模型元数据"""
    await CodeService.import_business_and_model(db=db, import_request=req)
    return api_success({}, msg="导入成功")


@router.get("/render/{gen_business_id}", response_model=ApiResponse[Dict[str, str]])
async def render_templates(gen_business_id: int, db: AsyncSession = Depends(get_db)):
    """渲染指定业务的所有模板代码，返回模板路径到代码内容的映射"""
    business = await GenBusinessService.get_gen_business_by_id(db, gen_business_id)
    if not business:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="代码生成业务不存在")

    rendered = await CodeService.render_tpl_code(db=db, business=business)
    return api_success(rendered, msg="渲染成功")


@router.get("/preview/{gen_business_id}")
async def preview_zip(gen_business_id: int, db: AsyncSession = Depends(get_db)):
    """打包并下载预览ZIP文件"""
    business = await GenBusinessService.get_gen_business_by_id(db, gen_business_id)
    if not business:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="代码生成业务不存在")

    zip_bytes = await CodeService.export_tpl_code_zip(db=db, business=business)
    filename = f"{business.app_name}-{business.filename}-code.zip"
    return StreamingResponse(io.BytesIO(zip_bytes), media_type="application/zip", headers={
        "Content-Disposition": f'attachment; filename="{filename}"'
    })


@router.post("/generate/{gen_business_id}", response_model=ApiResponse[List[str]])
async def generate_code(gen_business_id: int, overwrite: bool = False, db: AsyncSession = Depends(get_db)):
    """将渲染后的代码写入磁盘；返回写入的文件路径列表"""
    business = await GenBusinessService.get_gen_business_by_id(db, gen_business_id)
    if not business:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="代码生成业务不存在")

    written_paths = await CodeService.write_tpl_code(db=db, business=business, overwrite=overwrite)
    return api_success(written_paths, msg="生成成功")

